package com.sven.sentineldemo02;

import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.sven.sentineldemo02.service.TestService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.concurrent.TimeUnit;

@RestController
public class FlowLimitController {
    Logger logger = LoggerFactory.getLogger(FlowLimitController.class);
  /*  @GetMapping("/testA")
    public String testA(){
        return "-----testA";
    }

    @GetMapping("/testB")
    public String testB(){
        return "-----testB";
    }*/

    @Autowired
    TestService testService;

    @GetMapping("/testA")
    public String testA(){
        logger.info(Thread.currentThread().getName()+"：testA");
        return testService.common();
    }

    @GetMapping("/testB")
    public String testB(){
        return testService.common();
    }

    @GetMapping("/testC")
    public String testC(){
        try {
            TimeUnit.SECONDS.sleep(5);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return "----testC";
    }

    @GetMapping("/testD")
    public String testD(Integer id){
        if(id != null && id > 1){
            throw new RuntimeException("异常比例测试");
        }
        return "------------testD";
    }

    @GetMapping("/testE")
    public String testE(Integer id){
        if(id != null && id > 1){
            throw new RuntimeException("异常数测试");
        }
        return "------------testE";
    }

    @GetMapping("/testHotKey")
    @SentinelResource(value = "testHotKey", blockHandler = "handler_HotKey")
    public String testHotKey(@RequestParam(value = "hot1",required = false) String hot1,
                             @RequestParam(value = "hot2",required = false)String hot2,
                             @RequestParam(value = "hot3",required = false) String hot3){
        return "----testHotKey";
    }
    //处理异常方法，方法签名要和对应的接口方法保持一致
    public String handler_HotKey(String hot1, String hot2, String hot3, BlockException exception){
        return "系统繁忙稍后重试。。";
    }


    @GetMapping("/byResource")
    @SentinelResource(value = "byResource",blockHandler = "handler_resource")
    public String byResource(){
        return "-----byResource";
    }

    public String handler_resource(BlockException exception){
        return "系统繁忙";
    }

    @GetMapping("/byRest")
    @SentinelResource(value = "byRest")
    public String byRest(){
        return "-----byRest";
    }

    /**
     * 此方法用到了自定义限流处理类型CustomerBlockHandler
     * 中的handlerException1方法来处理限流逻辑。
     */
    @GetMapping("/bycustomer")
    @SentinelResource(value = "bycustomer",
            blockHandlerClass = CustomerBlockHandler.class,
            blockHandler = "handlerException1")
    public String bycustomer(){
        return "-----bycustomer";
    }



    @GetMapping("/consumer/fallback/{id}")
    //添加SentinelResource注解的fallback属性，同时设置方法来解决Java异常
    @SentinelResource(value = "falllback",fallback = "fallbackHandler")
    public String fallback(@PathVariable Long id){
        if(id<=3){
            //通过Ribbon发起远程访问
            return "-----bycustomer";
        }else{
            throw new NullPointerException("没有对应的数据记录");
        }
    }
    //保证方法签名基本保持一致，但是要添加异常类型参数
    public String fallbackHandler(Long id,Throwable e){
        return "出现未知商品id";
    }


    @GetMapping("/consumer/fallback2/{id}")
    //同时添加SentinelResource注解的fallback和blockHandler属性
    @SentinelResource(value = "falllback2",fallback = "fallbackHandler2",blockHandler = "blockHandler2")
    public String fallback2(@PathVariable Long id){
        if(id<=3){
            //通过Ribbon发起远程访问
            return "-----bycustomer";
        }else{
            throw new NullPointerException("没有对应的数据记录");
        }
    }
    //处理Java异常
    public String fallbackHandler2(Long id,Throwable e){
        return "处理Java异常-NullPointerException异常";
    }

    //处理Sentinel限流
    public String blockHandler2(Long id, BlockException e){
        return "处理Sentinel限流-BlockException限流";
    }



    @GetMapping("/order/test1")
    @SentinelResource(value = "test1")
    public String test1() throws InterruptedException {
        return "test1 ";
    }
}